标签
文档
报表
字数
2086 字
阅读时间
10 分钟
一、概述
POI在导出导出excel、导出csv、word时代码有点过于繁琐,Easypoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作。
easyPOI不能完全替代POI!
二、使用Demo
2.1 依赖
xml
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.0</version>
</dependency>
<!-- springboot整合依赖 -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>2.2 注解使用
注解方式主要用到的注解是@Excel注解,注解说明:
| 属性 | 类型 | 类型 | 说明 |
|---|---|---|---|
| name | String | null | 列名 |
| needMerge | boolean | fasle | 纵向合并单元格 |
| orderNum | String | "0" | 列的排序,支持name_id |
| replace | String[] | {} | 值得替换 导出是{a_id,b_id} 导入反过来 |
| savePath | String | "upload" | 导入文件保存路径 |
| type | int | 1 | 导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本 |
| width | double | 10 | 列宽 |
| height | double | 10 | 列高,后期打算统一使用@ExcelTarget的height,这个会被废弃,注意 |
| isStatistics | boolean | fasle | 自动统计数据,在追加一行统计,把所有数据都和输出这个处理会吞没异常,请注意这一点 |
| isHyperlink | boolean | false | 超链接,如果是需要实现接口返回对象 |
| isImportField | boolean | true | 校验字段,看看这个字段是不是导入的Excel中有,如果没有说明是错误的Excel,读取失败,支持name_id |
| exportFormat | String | "" | 导出的时间格式,以这个是否为空来判断是否需要格式化日期 |
| importFormat | String | "" | 导入的时间格式,以这个是否为空来判断是否需要格式化日期 |
| format | String | "" | 时间格式,相当于同时设置了exportFormat 和 importFormat |
| databaseFormat | String | "yyyyMMddHHmmss" | 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string类型,这个需要设置这个数据库格式,用以转换时间格式输出 |
| numFormat | String | "" | 数字格式化,参数是Pattern,使用的对象是DecimalFormat |
| imageType | int | 1 | 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的 |
| suffix | String | "" | 文字后缀,如% 90 变成90% |
| isWrap | boolean | true | 是否换行 即支持\n |
| mergeRely | int[] | {} | 合并单元格依赖关系,比如第二列合并是基于第一列 则{1}就可以了 |
| mergeVertical | boolean | fasle | 纵向合并内容相同的单元格 |
创建实体类
创建实体类,添加注解。dto必须要有空构造函数,否则会报错“对象创建错误”
java
import cn.afterturn.easypoi.excel.annotation.Excel;
import java.util.Date;
@Data
public class User {
@Excel(name = "编号", orderNum = "0", width = 5)
private Long id; //主键
@Excel(name = "入职日期", format = "yyyy-MM-dd",orderNum = "6", width = 15)
private Date hireDate;
private String deptId;
@Excel(name = "出生日期", format = "yyyy-MM-dd",orderNum = "7", width = 15)
private Date birthday;
@Excel(name = "照片", orderNum = "10",width = 15,type = 2,isImportField="true",savePath = "D:\\ftp")
private String photo;
@Excel(name = "现在居住地址", orderNum = "9", width = 30)
private String address;
}注解导出
java
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.lly.model.User;
import org.apache.poi.ss.usermodel.Workbook;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ExportDemo {
public static void main(String[] args) throws IOException {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User((long) i, new Date(), "科室id" + i, new Date(), "tupian" + i, "dizhi" + i);
userList.add(user);
}
//指定导出的格式是高版本的格式
ExportParams exportParams = new ExportParams("员工信息", "数据", ExcelType.XSSF);
// 直接使用EasyPOI提供的方法
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, User.class, userList);
String filename = "员工信息.xlsx";
//文件流
FileOutputStream fos = new FileOutputStream("E:\\" + filename);
workbook.write(fos);
fos.close();
}
}注解导入
java
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.lly.model.User;
import java.io.FileInputStream;
import java.util.List;
public class ImportDemo {
public static void main(String[] args) throws Exception {
String filename = "员工信息.xlsx";
//文件流
FileInputStream file = new FileInputStream("E:\\" + filename);
ImportParams importParams = new ImportParams();
//importParams.setStartSheetIndex(0); //指定sheet页
//importParams.setSheetNum(1); //从指定sheet开始,读取几个sheet页
importParams.setTitleRows(1); //有多少行的标题
importParams.setHeadRows(1);//有多少行的头
List<User> userList = ExcelImportUtil.importExcel(file,User.class,importParams);
for (User user : userList) {
System.out.println(user.toString());
}
file.close();
}
}2.3 模板方式导出数据
模板是处理复杂Excel的简单方法,复杂的Excel样式,可以用Excel直接编辑,完美的避开了代码编写样式的雷区,同时指令的支持,也提了模板的有效性 采用的写法是代表表达式,然后根据表达式里面的数据取值。easypoi不会改变excel原有的样式
java
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import org.apache.poi.ss.usermodel.Workbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExportTemplatDemo {
public static void main(String[] args) throws IOException {
// 获取模板的路径
File templatePath = new File("E:\\模板1.xlsx" );
// 读取模板文件
TemplateExportParams params = new TemplateExportParams(templatePath.getPath(),true);
Map<String, Object> map = new HashMap<>();
List<Object> list = new ArrayList<>();
for (int i = 0;i< 5 ; i++){
Map<String, Object> ll = new HashMap<>();
ll.put("id",i);
ll.put("hireDate","2023-11-0"+i);
ll.put("birthday","2023-11-"+i*2);
ll.put("address","测试地址"+i);
list.add(ll);
}
map.put("list",list);
ImageEntity image = new ImageEntity();
// image.setHeight(640); //测试发现 这里设置了长度和宽度在合并后的单元格中没有作用
// image.setWidth(380);
// 不合并就会有问题
image.setRowspan(3);//向下合并三行
image.setColspan(2);//向右合并两列
image.setUrl("D:\\ftp\\1.jpg");
map.put("photo",image);
Workbook workbook = ExcelExportUtil.exportExcel(params, map);
// 导出的文件名称
String filename="导出模板测试.xlsx";
//文件流
FileOutputStream fos = new FileOutputStream("E:\\" + filename);
workbook.write(fos);
fos.close();
}
}2.4 导出csv
csv的导出基本上和excel的导出一致,大体参数也是一致的
如果需要导出几百万数据时不可能全部加载到一个List中的,所以easyPOI的方式导出csv是支持不了太大的数据量的,如果导出几百万条数据还是得选择OpenCSV方式导出。
CsvExportParams 的参数描述如下
| 属性 | 类型 | 默认值 | 功能 |
|---|---|---|---|
| encoding | String | UTF8 | 文件编码 |
| spiltMark | String | , | 分隔符 |
| textMark | String | “ | 字符串识别,可以去掉,需要前后一致 |
| titleRows | int | 0 | 表格头,忽略 |
| headRows | int | 1 | 标题 |
| exclusions | String[] | 0 | 忽略的字段 |
java
import cn.afterturn.easypoi.csv.CsvExportUtil;
import cn.afterturn.easypoi.csv.entity.CsvExportParams;
import com.lly.model.User;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ExportCsvDemo {
public static void main(String[] args) throws IOException {
// 创建一个用来写入到csv文件中的writer
CsvExportParams params = new CsvExportParams();
// 设置忽略的列
params.setExclusions(new String[]{"照片"}); //这里写表头 中文
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User((long) i, new Date(), "科室id" + i, new Date(), "tupian" + i, "dizhi" + i);
userList.add(user);
}
FileOutputStream fos = new FileOutputStream("E:\\csv测试.csv");
CsvExportUtil.exportCsv(params, User.class, userList, fos);
fos.close();
}
}2.5 导出word
Word模板和Excel模板用法基本一致,支持的标签也是一致的,仅仅支持07版本的word也是只能生成后缀是docx的文档,poi对doc支持不好所以easyPOI中就没有支持doc
EasyPoi支持的指令以及作用
properties
三元运算 {{test ? obj:obj2}}
n: 表示 这个cell是数值类型 {{n:}}
le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
fn: 格式化数字 {{fn:(obj;###.00)}}
fe: 遍历数据,创建row
!fe: 遍历数据不创建row
$fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入
#fe: 横向遍历
v_fe: 横向遍历值
!if: 删除当前列 {{!if:(test)}}
单引号表示常量值 ‘’ 比如’1’ 那么输出的就是 1
&NULL& 空格
&INDEX& 表示循环中的序号,自动添加
]] 换行符 多行遍历导出
sum: 统计数据模板示例:
代码逻辑:
java
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExportWordDemo {
public static void main(String[] args) throws Exception {
File templatePath = new File("E:\\easypoi模板.docx");
// 把需要的数据放到map中,方便替换
Map<String,Object> params = new HashMap<String,Object>();
params.put("userName","张三");
params.put("hireDate","2023-10-01");
params.put("address","阿尔卑斯山");
// 下面是表格中需要的数据
List<Map> maplist = new ArrayList<>();
Map<String,Object> map = null;
for (int i = 0;i< 3 ;i++) {
map = new HashMap<String,Object>();
map.put("name","名称"+i);
map.put("price",100*i);
map.put("need",i%2 == 0?"需要":"不需要");
ImageEntity image = new ImageEntity();
image.setHeight(180);
image.setWidth(240);
image.setUrl("D:\\ftp\\1.jpg");
map.put("pic",image);
maplist.add(map);
}
// 把组建好的表格需要的数据放到大map中
params.put("list",maplist);
// 根据模板+数据 导出文档
XWPFDocument xwpfDocument = WordExportUtil.exportWord07(templatePath.getPath(), params);
FileOutputStream fos = new FileOutputStream("E:\\模板导出.docx" );
xwpfDocument.write(fos);
fos.close();
}
}导出效果: